<template>
  <el-dialog
    v-bind="attrs"
    :visible.sync="dialogVisible"
    append-to-body
    :close-on-click-modal="false"
    :show-close="false"
    width="35%"
    v-on="listeners"
  >
    <template #title>
      <div class="title">
        <div style="font-size: 18px;color: #303133;">{{ title }}</div>
        <i class="el-icon-close icon" @click="close" />
      </div>
    </template>
    <div class="dialog__content">
      <div class="list">

        <div class="list__select list__block">
          <div class="list__block__header">
            <el-input
              v-model="params.username"
              placeholder="请输入"
              size="medium"
              clearable
              @clear="handleClear"
              @change="handleSearch"
            />

            <div class="list__block__header__block">
              <div v-if="isNotSearch" class="actions">
                <div>
                  <el-checkbox
                    v-model="allSelect"
                    :indeterminate="isIndeterminate"
                    @change="handleCheckboxChange"
                  >
                    全选当前页
                  </el-checkbox>
                  <!--                  <el-button-->
                  <!--                    type="text"-->
                  <!--                    style="padding: 0;margin-left: 10px;"-->
                  <!--                    :disabled="!!value.length <= 0"-->
                  <!--                    @click="handleAllCancel"-->
                  <!--                  >-->
                  <!--                    全部取消-->
                  <!--                  </el-button>-->
                </div>

                <el-dropdown
                  v-if="showDeptSelect"
                  trigger="click"
                  @command="handleDepartmentChange"
                >
                  <span class="el-dropdown-link">
                    {{ dropdownTitle }}<i class="el-icon-arrow-down el-icon--right" />
                  </span>
                  <el-dropdown-menu
                    slot="dropdown"
                  >
                    <el-scrollbar
                      style="height: 300px;"
                      wrap-style="overflow-x:hidden;"
                    >
                      <el-dropdown-item :command="0">
                        全部
                      </el-dropdown-item>
                      <el-dropdown-item
                        v-for="item in departmentList"
                        :key="item.id"
                        :command="item.id"
                      >
                        {{ item.name }}
                      </el-dropdown-item>
                    </el-scrollbar>
                  </el-dropdown-menu>
                </el-dropdown>
              </div>
            </div>
          </div>
          <div
            ref="userListContainer"
            class="user-item"
          >
            <template v-if="userList.length > 0">
              <el-checkbox-group
                v-model="checkedValue"
                class="item-group"
              >
                <el-checkbox
                  v-for="item in userList"
                  :key="item.id"
                  :label="item.id"
                  :disabled="checkboxDisabled(item.id)"
                  class="item"
                >
                  <div class="item__info">
                    <template>
                      <el-avatar
                        v-if="item?.head_portrait || item?.avatar"
                        shape="square"
                        :src="item?.head_portrait || item?.avatar"
                        :size="38"
                        fit="cover"
                      />

                      <div v-else class="avatar--text">
                        {{ item.username.charAt(0) }}
                      </div>
                    </template>

                    <div class="name">{{ item.username }}</div>

                  </div>
                </el-checkbox>
              </el-checkbox-group>
              <div v-if="loading" class="load-text">
                <i class="el-icon-loading" /> 加载中...
              </div>
              <div v-if="nomore && !loading" class="load-text">——没有更多了——</div>
            </template>

            <el-empty
              v-if="!loading && userList.length <= 0"
              description="暂无数据"
            />

          </div>
        </div>

        <div class="list__selected list__block">
          <div class="list__block__header">

            <div v-if="!loading" class="list__block__header__block">
              <div class="tips">
                <template v-if="maxChoice !== Infinity">
                  已选择<el-button type="text">（{{ value.length }}/{{ maxChoice }}）</el-button>
                </template>

                <template v-else>
                  已选择<el-button type="text">（{{ value.length }}）</el-button>
                </template>
              </div>
            </div>
          </div>

          <div v-if="!loading && selectedFormat.length" class="selected-list">
            <div
              v-for="item in selectedFormat"
              :key="item.id"
              class="selected-list__item"
            >
              <template>
                <el-avatar
                  v-if="item?.head_portrait"
                  shape="square"
                  :src="item?.head_portrait"
                  :size="38"
                  style="flex-shrink:0;"
                  fit="cover"
                />

                <div v-else class="avatar--text">
                  {{ item.username.charAt(0) }}
                </div>
              </template>

              <div class="name">{{ item.username }}</div>

              <div class="el-icon-error icon" @click="handleRemove(item.id)" />
            </div>
          </div>

          <div v-else v-loading="loading" style="height: 380px;" />
        </div>
      </div>

      <div class="footer">
        <el-button size="mini" @click="handleCancel">取消</el-button>
        <el-button type="primary" size="mini" @click="handleConfirm">确定</el-button>
      </div>
    </div>

  </el-dialog>
</template>
<script>
import { getAllUser } from '@/api/v2/personnel'
import { getDept } from '@/api/v2/basic'
import { deepClone, treeToArray } from '@/utils'
export default {
  name: 'UserSelectModal',
  props: {
    value: {
      type: [String, Number, Array],
      default: ''
    },

    visible: {
      type: Boolean,
      required: true,
      default: false
    },

    type: {
      type: Number,
      default: null
    },

    multiple: {
      type: Boolean,
      default: true
    },

    maxChoice: {
      type: Number,
      default: Infinity
    },

    showDeptSelect: {
      type: Boolean,
      default: true
    },

    fetchUserFn: {
      type: Function,
      default: (params) => getAllUser(params)
    },

    title: {
      type: String,
      default: '选择人员'
    }

  },
  data() {
    return {
      params: {
        username: '',
        page: 1,
        paginate: 20,
        department_id: null,
        job_status: '[1]'
      },
      userList: [],
      departmentList: [],
      checkedUsers: [],
      loading: false,
      total: 0,
      valueBackup: null,
      isNotSearch: true,
      allUsers: [],
      isIndeterminate: false,
      allSelect: false
    }
  },
  computed: {
    attrs() {
      const attrs = { ...this.$attrs }
      return attrs
    },

    listeners() {
      const listeners = { ...this.$listeners }

      return listeners
    },

    dialogVisible: {
      get() {
        return this.visible
      },
      set(v) {
        this.$emit('update:visible', v)
      }
    },

    dropdownTitle() {
      const index = this.departmentList.findIndex(item => item.id === this.params.department_id)
      if (index <= -1) return '全部'

      return this.departmentList[index].name
    },

    nomore() {
      return this.userList.length >= this.total
    },

    checkboxDisabled() {
      return (id) => {
        const index = this.value.findIndex(item => item === id)
        return this.value.length >= this.maxChoice && index === -1
      }
    },

    checkedValue: {
      get() {
        return [...this.value]
      },
      set(v) {
        this.$emit('input', v)
      }
    },

    userListBackup() {
      return this.allUsers.map((item) => {
        return {
          id: item.id,
          username: item.username,
          head_portrait: item.head_portrait
        }
      })
    },

    selectedFormat() {
      return this.userListBackup.filter(item => this.value.includes(item.id))
    }

  },
  watch: {
    dialogVisible(n) {
      if (n) {
        if (Array.isArray(this.value)) this.valueBackup = deepClone(this.value)
        this.getUsers()
        this.$nextTick(() => {
          const container = this.$refs.userListContainer
          container.addEventListener('scroll', this.handleScroll)
        })
      }
    },
    value(n) {
      if (n.length && n.length === this.userList.length) {
        this.allSelect = true
        this.isIndeterminate = false
      } else if (n.length >= 1) {
        this.isIndeterminate = true
        this.allSelect = false
      } else {
        this.allSelect = false
        this.isIndeterminate = false
      }
    },

    userList: {
      handler(n) {
        if (n.length !== this.value.length && this.value.length !== 0) {
          this.allSelect = false
          this.isIndeterminate = true
        } else if (n.length === 0) {
          this.allSelect = false
          this.isIndeterminate = false
        } else if (n.length === this.value.length) {
          this.allSelect = true
          this.isIndeterminate = false
        }
        // if (this.allSelect) {
        //   this.handleCheckAll()
        // }
      },
      immediate: true
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      Promise.allSettled([
        this.getDepartmentsList(),
        this.getAllUser()
      ])
    },
    async getUsers() {
      this.loading = true
      try {
        const res = await this.fetchUserFn(this.params)
        console.log('res --------->', res)
        if (this.params.page === 1) {
          this.userList = res.data
        } else {
          this.userList.push(...res.data)
        }
        this.total = res.meta.total
      } catch (e) {
        console.log('e --------->', e)
        throw new Error(e?.response?.data?.message || '用户列表获取失败')
      } finally {
        this.loading = false
      }
    },

    async getAllUser() {
      const res = await getAllUser({ type: 2, job_status: '[1]' })
      this.allUsers = res.data
    },

    sleep(t = 500) {
      return new Promise(resolve => setTimeout(resolve, t))
    },

    async getDepartmentsList() {
      try {
        const res = await getDept()
        this.departmentList = treeToArray(res.data)
      } catch (error) {
        this.$message.error('获取部门数据失败')
      }
    },

    handleDepartmentChange(e) {
      this.params.department_id = e || null
      this.reset()
      this.getUsers()
    },

    reset() {
      this.userList = []
      this.params.page = 1
      this.total = 0
    },

    loadMore() {
      if (this.nomore) return
      this.params.page += 1
      this.getUsers()
    },

    handleScroll(e) {
      const container = this.$refs.userListContainer
      if (container) {
        const isAtBottom = container.scrollHeight - container.scrollTop === container.clientHeight
        if (isAtBottom && !this.loading) {
          this.loadMore()
        }
      }
    },

    handleSearch(e) {
      this.isNotSearch = !e
      this.reset()
      this.getUsers()
    },

    handleClear() {
      this.isNotSearch = true
      this.reset()
      this.getUsers()
    },

    handleAllCancel() {
      this.$emit('input', [])
    },

    handleRemove(id) {
      this.$emit('input', this.value.filter(item => item !== id))
    },

    handleConfirm() {
      this.$emit('onConfirm', this.value, this.handleGetValueMap())
      this.$emit('update:visible', false)
    },

    handleCancel() {
      this.$emit('input', this.valueBackup)
      this.$emit('update:visible', false)
    },

    close() {
      this.reset()
      this.params = this.$options.data().params
      this.allSelect = false
      this.isIndeterminate = false
      this.$emit('input', this.valueBackup)
      this.$emit('update:visible', false)
    },

    handleGetValueMap() {
      return this.userListBackup.filter(item => this.value.includes(item.id))
    },

    handleCheckAll() {
      const ids = this.userList.map(item => item.id)
      this.$emit('input', ids)
    },

    handleCheckboxChange(e) {
      console.log('e --------->', e)
      if (e) {
        this.handleCheckAll()
      } else {
        this.handleAllCancel()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
* {
  font-family: Microsoft YaHei, Microsoft YaHei;
}

.title {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .icon {
    font-size: 16px;
    color: #303133;
  }
}

.dialog__content {
  .list {
    padding: 30px 20px;
    display: flex;
    &__block {
      flex: 1;
      overflow: auto;

      &__header {
        &__block {
          margin-top: 20px;
          padding: 7px 0;
        }
      }

      .avatar--text {
        width: 38px;
        height: 38px;
        background-color: #1890FF;
        color: #fff;
        border-radius: 4px;
        text-align: center;
        line-height: 38px;
        font-size: 16px;
        flex-shrink:0;
      }

      .name {
        font-size: 14px;
        color: #303133;
        margin-left: 12px;
      }
    }

    &__select {
      border-right: 1px solid #DCDFE6;
      padding-right: 20px;

      .actions {
        display: flex;
        justify-content: space-between;
        align-items: center;

        .el-dropdown-link {
          color: #409EFF;
        }
      }

      .user-item {
        margin-top: 10px;
        height: 396px;
        overflow-y: auto;
        .item-group {
          display: flex;
          flex-direction: column;

          .item {
            margin-bottom: 10px;
            display: flex;
            align-items: center;

            &__info {
              display: flex;
              align-items: center;
            }
          }
        }

        .load-text {
          text-align: center;
          color: #A8ABB2;
          font-size: 14px;
        }
      }
    }

    &__selected {
      padding-left: 20px;

      .tips {
        font-size: 14px;
        color: #303133;
      }

      .selected-list {
        height: 396px;
        margin-top: 10px;
        overflow-y: auto;
        &__item {
          width: fit-content;
          padding: 8px;
          display: flex;
          justify-content: start;
          align-items: center;
          background-color: #F0F2F5;
          margin-bottom: 10px;
          border-radius: 4px;
          .name {
            margin-left: 4px !important;
          }

          .icon {
            margin-left: 8px;
            font-size: 18px;
            color: #A8ABB2;
          }
        }
      }
    }
  }

  .footer {
    padding: 10px 20px 20px 20px;
    display: flex;
    justify-content: end;
  }
}

::v-deep(.el-dialog__body) {
  padding: 0;
}

::v-deep(.el-avatar) {
  img {
    width: 100%;
  }
}

</style>
